package com.bookshop.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;

import com.bookshop.book.logic.Book;
import com.bookshop.book.logic.BookManagement;
import com.bookshop.book.logic.CatagoryManagement;
import com.bookshop.order.logic.OrderManagement;
import com.bookshop.order.state.OrderState;
import com.bookshop.promotion.logic.DiscountCoupons;
import com.bookshop.promotion.logic.EqualCoupons;
import com.bookshop.promotion.logic.PromotionConfig;
import com.bookshop.promotion.logic.PromotionItem;
import com.bookshop.promotion.logic.PromotionManagement;
import com.bookshop.sale.logic.SaleService;
import com.bookshop.sale.logic.ShowBookOfCart;
import com.bookshop.security.Register;
import com.bookshop.security.UserLogin;
import com.bookshop.tool.UserIdenfy;
import com.bookshop.user.identify.UserIdentity;
import com.bookshop.user.logic.CustomerInfo;
import com.bookshop.user.logic.User;
import com.bookshop.user.logic.UserManagement;
import com.bookshop.vo.CustomerVO;
import com.bookshop.vo.LoginVO;
import com.bookshop.vo.OrdersVO;
import com.bookshop.vo.PromotionConfigVO;
import com.bookshop.vo.PromotionItemVO;
import com.bookshop.vo.RegisterVO;
import com.bookshop.vo.SaleVO;
import com.bookshop.vo.SendCouponVO;
import com.bookshop.vo.UserVO;

/**
 * 
 * @author _Alpha
 */

public class BusinessService extends UnicastRemoteObject implements IBusinessService {
	private static final long serialVersionUID = 560202456724315828L;

	private final BookManagement mBookManagement;
	private final OrderManagement mOrderManagement;
	private final UserManagement mUserManagement;
	private final PromotionManagement mPromotionManagement;
	private final CatagoryManagement mCatagoryManagement;

	protected BusinessService() throws RemoteException {
		mBookManagement = new BookManagement();
		mOrderManagement = new OrderManagement();
		mUserManagement = new UserManagement();
		mPromotionManagement = new PromotionManagement();
		mCatagoryManagement = new CatagoryManagement();
	}

	@Override
	public String loginIn(LoginVO pLoginVO) throws RemoteException {
		UserLogin login = new UserLogin();
		return login.loginVerify(pLoginVO);
	}

	@Override
	public boolean register(RegisterVO pRegisterVO) throws RemoteException {
		Register register = new Register();
		return register.newUser(pRegisterVO);
	}

	@Override
	public CustomerVO showCustomerInfo(String pKey) throws RemoteException {
		CustomerVO customerVO = mUserManagement.getCustomer(pKey);
		return customerVO;
	}

	@Override
	public Book[] showCartInfo(String[] pIDs) throws RemoteException {
		return new ShowBookOfCart().execute(pIDs);
	}

	@Override
	public OrdersVO showCustomerOrder(String pKey, int pBegin, int pEnd) throws RemoteException {
		OrderManagement om = new OrderManagement();
		OrdersVO ordersVO = om.searchByUser(pKey, pBegin, pEnd);
		return ordersVO;
	}

	@Override
	public Book[] showSearchedBook(String pCategory, String pKeyword) throws RemoteException {
		return mCatagoryManagement.searchFromTheCatagory(pCategory, pKeyword);
	}

	@Override
	public Book[] showCollection(String pKey) throws RemoteException {
		User user = mUserManagement.getUserById(pKey);
		return ((CustomerInfo) (user.getUserInfo())).getCollectionBooks();
	}

	@Override
	public String[] showCategroy() throws RemoteException {
		return mCatagoryManagement.listCatagory();
	}

	@Override
	public boolean modifyCustomerInfo(CustomerVO pCustomerVO) throws RemoteException {
		return mUserManagement.modifyCustomerInfo(pCustomerVO);
	}

	@Override
	public double purchase(SaleVO pSaleVO) throws RemoteException {
		SaleService saleService = new SaleService(pSaleVO);
		return saleService.getCredits();
	}

	@Override
	public boolean collectBook(String pUserId, String pBookId) throws RemoteException {
		//XXX
		User user = mUserManagement.getUserById(pUserId);
		Book book = mBookManagement.searchByID(pBookId);
		ArrayList<Book> collectBook = new ArrayList<>();
		collectBook.add(book);
		return ((CustomerInfo) (user.getUserInfo())).collectBooks(collectBook);
	}

	@Override
	public boolean unCollectBook(String pUserId, String pBookId) throws RemoteException {
		User user = mUserManagement.getUserById(pUserId);
		Book book = mBookManagement.searchByID(pBookId);
		ArrayList<Book> collectBook = new ArrayList<>();
		collectBook.add(book);
		return ((CustomerInfo) (user.getUserInfo())).removeBooks(collectBook);
	}

	@Override
	public PromotionItemVO showPromotionItems(int pFromIndex, int pToIndex) throws RemoteException {
		PromotionItemVO promotionItermVO = mPromotionManagement.list(pFromIndex, pToIndex);
		return promotionItermVO;
	}

	@Override
	public boolean addPromotionItem(PromotionItem pItem) throws RemoteException {
		return mPromotionManagement.add(pItem);
	}

	@Override
	public boolean removePromotionItem(String pKey) throws RemoteException {
		return mPromotionManagement.remove(pKey) ;
	}

	@Override
	public void setPromotionInfo(PromotionConfigVO promotionConfigVO) throws RemoteException {
		PromotionConfig.instance().reset(promotionConfigVO.getDiscountRate(), promotionConfigVO.getEqualValue(), promotionConfigVO.getMaxUse(),
				promotionConfigVO.getRule());

	}

	@Override
	public PromotionConfigVO showPromotionConfig() throws RemoteException {
		return PromotionConfig.instance().getConfigVO();
	}

	@Override
	public CustomerVO[] showCustomerInfos(int pBegin, int pEnd) throws RemoteException {
		CustomerVO[] customerVOs = mUserManagement.getCustomers(pBegin, pEnd);
		return customerVOs;
	}

	@Override
	public Book[] showBooks(int pBegin, int pEnd) throws RemoteException {
		return mBookManagement.getBook(pBegin, pEnd);
	}

	@Override
	public boolean removeBook(String bookId) throws RemoteException {
		return mBookManagement.removeBook(bookId) ;
	}

	@Override
	public boolean modifyBook(Book pBook) throws RemoteException {
		String id = pBook.getId();
		boolean isSuccess = true;
		isSuccess &= mBookManagement.modifyAuthor(id, pBook.getAuthor());
		isSuccess &= mBookManagement.modifyCatagory(id, pBook.getCatagory());
		isSuccess &= mBookManagement.modifyDescription(id, pBook.getDescription());
		isSuccess &= mBookManagement.modifyImage(id, pBook.getImage());
		isSuccess &= mBookManagement.modifyISBN(id, pBook.getISBN());
		isSuccess &= mBookManagement.modifyName(id, pBook.getName());
		isSuccess &= mBookManagement.modifyNum(id, pBook.getNum());
		isSuccess &= mBookManagement.modifyPress(id, pBook.getPress());
		isSuccess &= mBookManagement.modifyPrice(id, pBook.getPrice());
		isSuccess &= mBookManagement.modifyPublishDate(id, pBook.getPublishDate());
		return isSuccess; 
	}

	@Override
	public boolean addBook(Book pBook) throws RemoteException {
		return mBookManagement.addBook(pBook);
	}

	@Override
	public boolean setCatagry(String pOriginalCatagory, String pNewCatagory) throws RemoteException {
		return mCatagoryManagement.modify(pOriginalCatagory, pNewCatagory) ;
	}

	@Override
	public boolean removeCategory(String pCatagory) throws RemoteException {
		return mCatagoryManagement.remove(pCatagory);
	}

	@Override
	public void sendCoupons(SendCouponVO pSendCouponVO) throws RemoteException {
		User user = mUserManagement.getUserById(pSendCouponVO.getAccount());
		PromotionConfig config = PromotionConfig.instance();
		double equalPerValue = config.getEqualValue();
		double discountRate = config.getDiscountRate();
		EqualCoupons equalCoupons = new EqualCoupons(equalPerValue, pSendCouponVO.getEqualCount());
		DiscountCoupons discountCoupons = new DiscountCoupons(discountRate, pSendCouponVO.getDiscountCount());
		((CustomerInfo) user.getUserInfo()).addCoupons(equalCoupons, discountCoupons);
	}

	@Override
	public OrdersVO showCustomerOrders(int pBegin, int pEnd) throws RemoteException {
		return mOrderManagement.list(pBegin, pEnd);
	}

	@Override
	public boolean changeOrderState(String pOrderId, OrderState pState) throws RemoteException {
		return mOrderManagement.modifyState(pOrderId, pState);
	}

	@Override
	public boolean modifyUser(String pAccount, String pPassword) throws RemoteException {
		return mUserManagement.modifyPassword(pAccount, pPassword);
	}

	@Override
	public boolean removeUsers(String pAccount) throws RemoteException {
		return mUserManagement.removeUser(pAccount);
	}

	@Override
	public boolean add(String pAccount, String pPassword, String pIdentity) throws RemoteException {
		User newUser = new User(pAccount, pPassword, UserIdenfy.recognize(pIdentity), null);
		boolean result = mUserManagement.addUser(newUser);
		return result;
	}

	@Override
	public UserVO showUser(int pBegin, int pEnd, UserIdentity pIdentity) throws RemoteException {
		return mUserManagement.getUsers(pBegin, pEnd, pIdentity);
	}

	@Override
	public boolean addCategory(String pCategory) throws RemoteException {
		return mCatagoryManagement.add(pCategory);
	}

}
